package com.minimalist.lindi.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.Assert;
import com.minimalist.common.config.exception.BusinessException;
import com.minimalist.common.config.mybatis.bo.PageResp;
import com.minimalist.common.entity.lindi.enums.LindiIndexChangeRecordEnum;
import com.minimalist.common.entity.lindi.po.LindiIndexChangeRecord;
import com.minimalist.common.entity.lindi.vo.indexchangerecord.LindiIndexChangeRecordQueryVO;
import com.minimalist.common.entity.lindi.vo.indexchangerecord.LindiIndexChangeRecordVO;
import com.minimalist.common.utils.UnqIdUtil;
import com.minimalist.lindi.manager.LindiIndexManager;
import com.minimalist.lindi.mapper.LindiIndexChangeRecordMapper;
import com.minimalist.lindi.service.LindiIndexChangeRecordService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;

/**
 * 林地指标平台_林地指标变更记录表 服务层实现。
 *
 * @author 11987
 * @since 2025-05-13
 */
@Service
public class LindiIndexChangeRecordServiceImpl extends ServiceImpl<LindiIndexChangeRecordMapper, LindiIndexChangeRecord> implements LindiIndexChangeRecordService{

    @Autowired
    private LindiIndexChangeRecordMapper mapper;

    @Autowired
    private LindiIndexManager lindiIndexManager;

    @Override
    public void addIndexChangeRecord(LindiIndexChangeRecordVO recordVO){
        LindiIndexChangeRecord record = BeanUtil.copyProperties(recordVO
                , LindiIndexChangeRecord.class);
        LindiIndexChangeRecord old = mapper
                .selectIndexChangeRecordByTradeApplicationIdAndTownName(recordVO);
        Assert.isNull(old, () -> new BusinessException(
                LindiIndexChangeRecordEnum.ErrorMsgEnum.RECORD_EXIST_ERROR.getDesc()));
        record.setIndexChangeRecordId(UnqIdUtil.uniqueId());
        int insert = mapper.insert(record, true);
        Assert.isTrue(insert == 1, () -> new BusinessException(
                LindiIndexChangeRecordEnum.ErrorMsgEnum.ADD_RECORD_ERROR.getDesc()));
    }

    @Override
    public void deleteIndexChangeRecordByIndexChangeRecordId(Long indexChangeRecordId){
        LindiIndexChangeRecord record = mapper
                .selectIndexChangeRecordByIndexChangeRecordId(indexChangeRecordId);
        Assert.notNull(record, () -> new BusinessException(LindiIndexChangeRecordEnum
                .ErrorMsgEnum.RECORD_NOT_FOUND.getDesc()));
        int delete = mapper.delete(record);
        Assert.isTrue(delete == 1, () -> new BusinessException(
                LindiIndexChangeRecordEnum.ErrorMsgEnum.DELETE_RECORD_ERROR.getDesc()));
    }

    @Override
    public void updateIndexChangeRecordByIndexChangeRecordId(
            LindiIndexChangeRecordVO recordVO){
        LindiIndexChangeRecord record = mapper
                .selectIndexChangeRecordByIndexChangeRecordId(recordVO.getIndexChangeRecordId());
        Assert.notNull(record, () -> new BusinessException(LindiIndexChangeRecordEnum
                .ErrorMsgEnum.RECORD_NOT_FOUND.getDesc()));
        BeanUtil.copyProperties(recordVO, record
                , CopyOptions.create().ignoreNullValue());
        BigDecimal tradeIndex = lindiIndexManager.getEnableTradeIndexByTownName(
                record.getTownName());

        // 校验可交易指标加上原有变更数量是否足够支持新的变更数量
        BigDecimal availableIndex = tradeIndex.add(new BigDecimal(record.getChangeQuantity()));
        Assert.isTrue(availableIndex.compareTo(
                        new BigDecimal(recordVO.getChangeQuantity())) >= 0,
                () -> new BusinessException(LindiIndexChangeRecordEnum
                        .ErrorMsgEnum.AVAILABLE_INDEX_NOT_ENOUGH.getDesc()));

        int update = mapper.update(record);
        Assert.isTrue(update == 1, () -> new BusinessException(
                LindiIndexChangeRecordEnum.ErrorMsgEnum.UPDATE_RECORD_ERROR.getDesc()));
    }

    @Override
    public PageResp<LindiIndexChangeRecordVO> getPageIndexChangeRecordList(LindiIndexChangeRecordQueryVO queryVO){
        //分页查询
        Page<LindiIndexChangeRecord> recordPage = mapper
                .selectPageIndexChangeRecordList(queryVO);
        //数据转换
        List<LindiIndexChangeRecordVO> recordVOList = BeanUtil.copyToList(recordPage.getRecords()
                , LindiIndexChangeRecordVO.class);
        return new PageResp<>(recordVOList, recordPage.getTotalRow());
    }

    @Override
    public LindiIndexChangeRecordVO getIndexChangeRecordByIndexChangeRecordId(Long indexChangeRecordId){
        LindiIndexChangeRecord record = mapper
                .selectIndexChangeRecordByIndexChangeRecordId(indexChangeRecordId);
        Assert.notNull(record, () -> new BusinessException(LindiIndexChangeRecordEnum.ErrorMsgEnum
                .RECORD_NOT_FOUND.getDesc()));
        return BeanUtil.copyProperties(record, LindiIndexChangeRecordVO.class);
    }
}
